home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / share / pyshared / DistUpgrade / distinfo.py < prev    next >
Text File  |  2009-09-25  |  10KB  |  287 lines

  1. #  distinfo.py - provide meta information for distro repositories
  2. #
  3. #  Copyright (c) 2005 Gustavo Noronha Silva <kov@debian.org>
  4. #  Copyright (c) 2006-2007 Sebastian Heinlein <glatzor@ubuntu.com>
  5. #
  6. #  Authors: Gustavo Noronha Silva <kov@debian.org>
  7. #           Sebastian Heinlein <glatzor@ubuntu.com>
  8. #
  9. #  This program is free software; you can redistribute it and/or
  10. #  modify it under the terms of the GNU General Public License as
  11. #  published by the Free Software Foundation; either version 2 of the
  12. #  License, or (at your option) any later version.
  13. #
  14. #  This program is distributed in the hope that it will be useful,
  15. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. #  GNU General Public License for more details.
  18. #
  19. #  You should have received a copy of the GNU General Public License
  20. #  along with this program; if not, write to the Free Software
  21. #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  22. #  USA
  23.  
  24. import os
  25. import gettext
  26. from os import getenv
  27. import ConfigParser
  28. import re
  29.  
  30. import apt_pkg
  31.  
  32.  
  33. def _(s):
  34.     return gettext.dgettext("python-apt", s)
  35.  
  36.  
  37. class Template:
  38.  
  39.     def __init__(self):
  40.         self.name = None
  41.         self.child = False
  42.         self.parents = []          # ref to parent template(s)
  43.         self.match_name = None
  44.         self.description = None
  45.         self.base_uri = None
  46.         self.type = None
  47.         self.components = []
  48.         self.children = []
  49.         self.match_uri = None
  50.         self.mirror_set = {}
  51.         self.distribution = None
  52.         self.available = True
  53.  
  54.     def has_component(self, comp):
  55.         ''' Check if the distribution provides the given component '''
  56.         return comp in map(lambda c: c.name, self.components)
  57.  
  58.     def is_mirror(self, url):
  59.         ''' Check if a given url of a repository is a valid mirror '''
  60.         proto, hostname, dir = split_url(url)
  61.         if hostname in self.mirror_set:
  62.             return self.mirror_set[hostname].has_repository(proto, dir)
  63.         else:
  64.             return False
  65.  
  66.  
  67. class Component:
  68.  
  69.     def __init__(self, name, desc=None, long_desc=None):
  70.         self.name = name
  71.         self.description = desc
  72.         self.description_long = long_desc
  73.  
  74.     def get_description(self):
  75.         if self.description_long is not None:
  76.             return self.description_long
  77.         elif self.description is not None:
  78.             return self.description
  79.         else:
  80.             return None
  81.  
  82.     def set_description(self, desc):
  83.         self.description = desc
  84.  
  85.     def set_description_long(self, desc):
  86.         self.description_long = desc
  87.  
  88.     def get_description_long(self):
  89.         return self.description_long
  90.  
  91.  
  92. class Mirror:
  93.     ''' Storage for mirror related information '''
  94.  
  95.     def __init__(self, proto, hostname, dir, location=None):
  96.         self.hostname = hostname
  97.         self.repositories = []
  98.         self.add_repository(proto, dir)
  99.         self.location = location
  100.  
  101.     def add_repository(self, proto, dir):
  102.         self.repositories.append(Repository(proto, dir))
  103.  
  104.     def get_repositories_for_proto(self, proto):
  105.         return filter(lambda r: r.proto == proto, self.repositories)
  106.  
  107.     def has_repository(self, proto, dir):
  108.         if dir is None:
  109.             return False
  110.         for r in self.repositories:
  111.             if r.proto == proto and dir in r.dir:
  112.                 return True
  113.         return False
  114.  
  115.     def get_repo_urls(self):
  116.         return map(lambda r: r.get_url(self.hostname), self.repositories)
  117.  
  118.     def get_location(self):
  119.         return self.location
  120.  
  121.     def set_location(self, location):
  122.         self.location = location
  123.  
  124.  
  125. class Repository:
  126.  
  127.     def __init__(self, proto, dir):
  128.         self.proto = proto
  129.         self.dir = dir
  130.  
  131.     def get_info(self):
  132.         return self.proto, self.dir
  133.  
  134.     def get_url(self, hostname):
  135.         return "%s://%s/%s" % (self.proto, hostname, self.dir)
  136.  
  137.  
  138. def split_url(url):
  139.     ''' split a given URL into the protocoll, the hostname and the dir part '''
  140.     return map(lambda a, b: a, re.split(":*\/+", url, maxsplit=2),
  141.                [None, None, None])
  142.  
  143.  
  144. class DistInfo:
  145.  
  146.     def __init__(self,
  147.                  dist = None,
  148.                  base_dir = "/usr/share/python-apt/templates"):
  149.         self.metarelease_uri = ''
  150.         self.templates = []
  151.         self.arch = apt_pkg.Config.Find("APT::Architecture")
  152.  
  153.         location = None
  154.         match_loc = re.compile(r"^#LOC:(.+)$")
  155.         match_mirror_line = re.compile(
  156.             r"^(#LOC:.+)|(((http)|(ftp)|(rsync)|(file)|(https))://"
  157.             r"[A-Za-z0-9/\.:\-_@]+)$")
  158.         #match_mirror_line = re.compile(r".+")
  159.  
  160.         if not dist:
  161.             pipe = os.popen("lsb_release -i -s")
  162.             dist = pipe.read().strip()
  163.             pipe.close()
  164.             del pipe
  165.  
  166.         self.dist = dist
  167.  
  168.         map_mirror_sets = {}
  169.  
  170.         dist_fname = "%s/%s.info" % (base_dir, dist)
  171.         dist_file = open(dist_fname)
  172.         if not dist_file:
  173.             return
  174.         template = None
  175.         component = None
  176.         for line in dist_file:
  177.             tokens = line.split(':', 1)
  178.             if len(tokens) < 2:
  179.                 continue
  180.             field = tokens[0].strip()
  181.             value = tokens[1].strip()
  182.             if field == 'ChangelogURI':
  183.                 self.changelogs_uri = _(value)
  184.             elif field == 'MetaReleaseURI':
  185.                 self.metarelease_uri = value
  186.             elif field == 'Suite':
  187.                 self.finish_template(template, component)
  188.                 component=None
  189.                 template = Template()
  190.                 template.name = value
  191.                 template.distribution = dist
  192.                 template.match_name = "^%s$" % value
  193.             elif field == 'MatchName':
  194.                 template.match_name = value
  195.             elif field == 'ParentSuite':
  196.                 template.child = True
  197.                 for nanny in self.templates:
  198.                     # look for parent and add back ref to it
  199.                     if nanny.name == value:
  200.                         template.parents.append(nanny)
  201.                         nanny.children.append(template)
  202.             elif field == 'Available':
  203.                 template.available = value
  204.             elif field == 'RepositoryType':
  205.                 template.type = value
  206.             elif field == 'BaseURI' and not template.base_uri:
  207.                 template.base_uri = value
  208.             elif field == 'BaseURI-%s' % self.arch:
  209.                 template.base_uri = value
  210.             elif field == 'MatchURI' and not template.match_uri:
  211.                 template.match_uri = value
  212.             elif field == 'MatchURI-%s' % self.arch:
  213.                 template.match_uri = value
  214.             elif (field == 'MirrorsFile' or
  215.                   field == 'MirrorsFile-%s' % self.arch):
  216.                 if value not in map_mirror_sets:
  217.                     mirror_set = {}
  218.                     try:
  219.                         mirror_data = filter(match_mirror_line.match,
  220.                                              [x.strip() for x in open(value)])
  221.                     except Exception:
  222.                         print "WARNING: Failed to read mirror file"
  223.                         mirror_data = []
  224.                     for line in mirror_data:
  225.                         if line.startswith("#LOC:"):
  226.                             location = match_loc.sub(r"\1", line)
  227.                             continue
  228.                         (proto, hostname, dir) = split_url(line)
  229.                         if hostname in mirror_set:
  230.                             mirror_set[hostname].add_repository(proto, dir)
  231.                         else:
  232.                             mirror_set[hostname] = Mirror(
  233.                                 proto, hostname, dir, location)
  234.                     map_mirror_sets[value] = mirror_set
  235.                 template.mirror_set = map_mirror_sets[value]
  236.             elif field == 'Description':
  237.                 template.description = _(value)
  238.             elif field == 'Component':
  239.                 if component and not template.has_component(component.name):
  240.                     template.components.append(component)
  241.                 component = Component(value)
  242.             elif field == 'CompDescription':
  243.                 component.set_description(_(value))
  244.             elif field == 'CompDescriptionLong':
  245.                 component.set_description_long(_(value))
  246.         self.finish_template(template, component)
  247.         template=None
  248.         component=None
  249.  
  250.     def finish_template(self, template, component):
  251.         " finish the current tempalte "
  252.         if not template:
  253.             return
  254.         # reuse some properties of the parent template
  255.         if template.match_uri is None and template.child:
  256.             for t in template.parents:
  257.                 if t.match_uri:
  258.                     template.match_uri = t.match_uri
  259.                     break
  260.         if template.mirror_set == {} and template.child:
  261.             for t in template.parents:
  262.                 if t.match_uri:
  263.                     template.mirror_set = t.mirror_set
  264.                     break
  265.         if component and not template.has_component(component.name):
  266.             template.components.append(component)
  267.             component = None
  268.         self.templates.append(template)
  269.  
  270.  
  271. if __name__ == "__main__":
  272.     d = DistInfo("Ubuntu", "/usr/share/python-apt/templates")
  273.     print d.changelogs_uri
  274.     for template in d.templates:
  275.         print "\nSuite: %s" % template.name
  276.         print "Desc: %s" % template.description
  277.         print "BaseURI: %s" % template.base_uri
  278.         print "MatchURI: %s" % template.match_uri
  279.         if template.mirror_set != {}:
  280.             print "Mirrors: %s" % template.mirror_set.keys()
  281.         for comp in template.components:
  282.             print " %s -%s -%s" % (comp.name,
  283.                                    comp.description,
  284.                                    comp.description_long)
  285.         for child in template.children:
  286.             print "  %s" % child.description
  287.